package cn.wtg.kotlinlib.net.downloadAndUpload.download

import kotlin.Throws
import okhttp3.MediaType
import okhttp3.ResponseBody
import okio.*
import java.io.IOException

/**
 * author: wtg  2019/9/2 0002
 * desc: 现在进度的监听
 */
class DownloadResponseBody : ResponseBody {
    private var responseBody: ResponseBody
    private var bufferedSource: BufferedSource? = null
    private var downloadListener: DownloadListener?
    private var startPoint: Long = -1

    constructor(responseBody: ResponseBody, progressListener: DownloadListener?) {
        this.responseBody = responseBody
        downloadListener = progressListener
    }

    constructor(responseBody: ResponseBody, progressListener: DownloadListener?, startPoint: Long) {
        this.responseBody = responseBody
        downloadListener = progressListener
        this.startPoint = startPoint
    }

    override fun contentType(): MediaType? {
        return responseBody.contentType()
    }

    override fun contentLength(): Long {
        return responseBody.contentLength()
    }

    override fun source(): BufferedSource {
        if (bufferedSource == null) {
            bufferedSource = source(responseBody.source()).buffer()
        }
        return bufferedSource!!
    }

    private fun source(source: Source): Source {
        return object : ForwardingSource(source) {
            var totalBytesRead = 0L
            @Throws(IOException::class)
            override fun read(sink: Buffer, byteCount: Long): Long {
                val bytesRead = super.read(sink, byteCount)
                if (totalBytesRead == 0L) {
                    downloadListener!!.onStartDownload(responseBody.contentLength())
                }
                totalBytesRead += if (bytesRead != -1L) bytesRead else 0
                if (null != downloadListener) {
                    if (startPoint == -1L) {
                        downloadListener!!.onProgress(
                            totalBytesRead,
                            responseBody.contentLength(),
                            bytesRead == -1L
                        )
                    } else {
                        downloadListener!!.onProgress(
                            totalBytesRead + startPoint,
                            responseBody.contentLength(),
                            bytesRead == -1L
                        )
                    }
                }
                return bytesRead
            }
        }
    }

    interface DownloadListener {
        fun onStartDownload(length: Long)
        fun onProgress(progress: Long, total: Long, done: Boolean)
        fun onFail(errorInfo: String?)
    }
}